package us.mmapp;

import java.io.File;
import java.util.ArrayList;

import us.mmapp.entities.ObjectEntity;
import us.mmapp.interfaces.MediaSynchListener;
import us.mmapp.interfaces.MediaUploaderListener;
import us.mmapp.services.MediaUploader;
import us.mmapp.services.ObjectSyncService;
import us.mmapp.util.ApplicationData;
import us.mmapp.util.DBOpenHelper;
import us.mmapp.util.FileNameUtil;
import us.mmapp.util.ThumbnailUtil;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TableRow.LayoutParams;
import android.widget.TextView;

public class InfoActivity extends Activity implements LocationListener,
		OnClickListener, MediaSynchListener, MediaUploaderListener
{
	private LocationManager lm;
	private Button done, cancel, add_field, delete, remove_field;
	private double latitude, longitude;
	private String fileLocation, fileName;
	private boolean firstTime;
	private long serverID;
	private long uid;
	private int type;
	private long dateCreated;
	private String url;
	private String url_thumb;
	private String local_thumb_location;
	private ArrayList<EditText> extraFieldTitle;
	private ArrayList<EditText> extraFieldData;
	private CheckBox synchNow;
	private ProgressDialog mProgress;
	private long mRequestId;
	private ObjectEntity mObjectEntity;
	private long mRequestIdUploader;
	@Override
	public void onPause()
	{
		super.onPause();
		ObjectSyncService.deattach(this);
		MediaUploader.deattach(this);
		ApplicationData.refresh();
	}
	@Override
	public void onResume()
	{
		super.onResume();
		ObjectSyncService.attach(this);
		MediaUploader.attach(this);
	}
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		
		setContentView(R.layout.info);
		
		//hide keyboard if first time load
		getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
		
		extraFieldTitle=new ArrayList<EditText>();
		extraFieldData=new ArrayList<EditText>();
		Bundle bundle = this.getIntent().getExtras();
		firstTime=bundle.getBoolean("new");
		
		synchNow = (CheckBox) findViewById(R.id.checkboxSynch);
		
		if(firstTime)
		{
			firstTimeLoad();
		}
		else
		{
			load();
		}
		done = (Button) findViewById(R.id.done);
		cancel = (Button) findViewById(R.id.cancel);
		add_field=(Button)findViewById(R.id.add_field);
		delete=(Button)findViewById(R.id.widget46);
		remove_field=(Button)findViewById(R.id.remove_field);
		done.setOnClickListener(this);
		cancel.setOnClickListener(this);
		add_field.setOnClickListener(this);
		delete.setOnClickListener(this);
		remove_field.setOnClickListener(this);
		if(firstTime)
		{
			delete.setVisibility(Button.INVISIBLE);
		}
		ImageView iv=(ImageView)findViewById(R.id.picture);
		final InfoActivity infoActivity=this;
		iv.setOnClickListener(new OnClickListener()
		{
			
			@Override
			public void onClick(View v)
			{
				String mediaSource;
				if(fileLocation==null || fileLocation.equals(""))
					mediaSource=url;
				else
					mediaSource=fileLocation;
				if(type==FileNameUtil.VIDEO || type==FileNameUtil.AUDIO)
				{
					Intent tostart = new Intent(Intent.ACTION_VIEW);
					tostart.setDataAndType(Uri.parse(mediaSource), "video/*");
					startActivity(tostart);
				}
				else if(type==FileNameUtil.PICTURE)
				{
					
					Intent intent=new Intent();
					intent.setClass(infoActivity, ViewImageActivity.class);
					Bundle bundle=new Bundle();
					bundle.putInt("keyword", (int)serverID);
					intent.putExtras(bundle);
					startActivity(intent);
				}
			}
		});
	}
	private void firstTimeLoad()
	{
		
		Bundle bundle=this.getIntent().getExtras();
		TextView tv = (TextView) findViewById(R.id.itemName);
		String[] s = bundle.getString("keyword").split("/");
		fileName = s[s.length - 1];
		tv.setText(fileName);
		fileLocation = bundle.getString("keyword");
		local_thumb_location=ThumbnailUtil.saveThumbnail(this, bundle.getString("keyword"));
		
		SharedPreferences settings = getSharedPreferences("LOGIN", 0);
	       
        SharedPreferences settings1 = getSharedPreferences("ObjectID", 0);
        int unsyncedSID=settings1.getInt("OID", -1);
        
	    SharedPreferences.Editor editor = settings1.edit();
	    editor.putInt("OID", (unsyncedSID-1));
	    editor.commit();
        
        uid = settings.getLong("uid", 0);
        serverID=unsyncedSID;
        url="";
        url_thumb="";
        type=FileNameUtil.getFileType(fileName);
        dateCreated=System.currentTimeMillis()/1000;
        fileName=unsyncedSID+"";
        getGPSLocation();
        ImageView iv = (ImageView) findViewById(R.id.picture);
		ThumbnailUtil.setImageView(this, (int)serverID, iv, true);
        // Show the synch now
        synchNow.setVisibility(CheckBox.VISIBLE);
        synchNow.setChecked(true);
        RadioButton b=(RadioButton)findViewById(R.id.personal);
        b.setChecked(true);
	}
	private void load()
	{
		TextView tv = (TextView) findViewById(R.id.itemName);
		DBOpenHelper data=new DBOpenHelper(this, "mmAppDB", DBOpenHelper.VERSION);
		SQLiteDatabase db=data.getReadableDatabase();
		int osid=this.getIntent().getExtras().getInt("keyword");
		Cursor dbObjects=db.rawQuery("SELECT * FROM OBJECTS WHERE "+DBOpenHelper.ID+"='"+osid+"'", null);
        if(dbObjects.moveToNext())
        {
        	String title=dbObjects.getString(5);
        	String description=dbObjects.getString(6);
        	int privacy=dbObjects.getInt(7);
        	
        	((TextView)findViewById(R.id.titleEdit)).setText(title);
        	((EditText)findViewById(R.id.descriptionEdit)).setText(description);
        	switch(privacy)
        	{
        	case 0: ((RadioButton)findViewById(R.id.personal)).setChecked(true); break;
        	case 1: ((RadioButton)findViewById(R.id.Friends)).setChecked(true); break;
        	}
        	fileName=dbObjects.getString(0);
        	serverID=dbObjects.getLong(1);   
        	uid=dbObjects.getInt(2);
        	fileLocation=dbObjects.getString(3);
        	type=dbObjects.getInt(4);
        	dateCreated=dbObjects.getLong(8);
        	latitude=dbObjects.getDouble(10);
        	longitude=dbObjects.getDouble(11);
        	url=dbObjects.getString(12);
        	url_thumb=dbObjects.getString(13);
        	local_thumb_location=dbObjects.getString(15);
        }
        dbObjects.close();
        ImageView iv = (ImageView) findViewById(R.id.picture);
        tv.setText(fileName);
        ThumbnailUtil.setImageView(this, (int)serverID, iv, true);
        dbObjects=db.rawQuery("SELECT * FROM TAGS WHERE ID='"+serverID+"'", null);
        StringBuilder tags=new StringBuilder();
        while(dbObjects.moveToNext())
        {
        	if(dbObjects.getString(1)!=null)
        		tags.append(dbObjects.getString(1)+" ");
        }
        dbObjects.close();
        ((TextView)findViewById(R.id.tagsEdit)).setText(tags);
        
        dbObjects=db.rawQuery("Select * from extra_fields where oid="+serverID+" order by order_id", null);
        while(dbObjects.moveToNext())
        {
        	addExtraFieldEditText(dbObjects.getString(0), dbObjects.getString(1));
        }
        
        db.close();
        dbObjects.close();
        data.close();
        // Show the synch now
        synchNow.setVisibility(CheckBox.VISIBLE);
        synchNow.setChecked(true);
	}
	public void cancel()
	{
		if(firstTime)
		{
			try
			{
				File file=new File(fileLocation);
				if(file!=null)
					file.delete();
				file=new File(local_thumb_location);
				if(file!=null)
					file.delete();
			}
			catch(NullPointerException e)
			{}
		}
		finish();
	}
	private boolean allInputCharactersValid()
	{
		String titleText = ((TextView) findViewById(R.id.titleEdit)).getText().toString();
		String descriptionText = ((TextView) findViewById(R.id.descriptionEdit)).getText().toString();
		String tagsText = ((TextView) findViewById(R.id.tagsEdit)).getText().toString();
		if (!validInput(titleText) || !validInput(descriptionText) || !validInput(tagsText))
		{
			return false;
		}
		for(int i=0; i<extraFieldData.size(); i++)
		{
			if(!validInput(extraFieldData.get(i).getText().toString()) || !validInput(extraFieldTitle.get(i).getText().toString()))
			{
				return false;
			}
		}
		return true;
	}
	private boolean allFieldsProperInput()
	{
		String titleText = ((TextView) findViewById(R.id.titleEdit)).getText().toString();
		if(titleText.equals(""))
		{
			return false;
		}
		for(int i=0; i<extraFieldTitle.size(); i++)
		{
			if(extraFieldTitle.get(i).getText().toString().equals(""))
			{
				return false;
			}
		}
		return true;
	}
	
	public void onClick(View v)
	{
		if (v.equals(done))
		{
			String titleText = ((TextView) findViewById(R.id.titleEdit)).getText().toString();
			String descriptionText = ((TextView) findViewById(R.id.descriptionEdit)).getText().toString();
			String tagsText = ((TextView) findViewById(R.id.tagsEdit)).getText().toString();
			if (!allInputCharactersValid())
			{
				invalidTextPopup();
			}
			else if(!allFieldsProperInput())
			{
				emptyTextPopup();
			}
			else
			{
				int privacyLevel = ((RadioGroup) findViewById(R.id.privacyLevel)).getCheckedRadioButtonId();
				if (privacyLevel == -1 || privacyLevel == R.id.personal)
				{
					privacyLevel = 0;
				}
				else if (privacyLevel == R.id.Friends)
				{
					privacyLevel = 1;
				}
				long timestamp = System.currentTimeMillis()/1000;
				
				DBOpenHelper data = new DBOpenHelper(this, "mmAppDB", DBOpenHelper.VERSION);
				SQLiteDatabase db = data.getWritableDatabase();
				
				ContentValues cv=new ContentValues();
				
				try
				{
					db.execSQL("Delete from extra_fields where oid="+serverID);
				}
				catch(Exception e)
				{
					
				}
				for(int i=0; i<extraFieldData.size(); i++)
				{
					cv.put("FIELD", extraFieldTitle.get(i).getText().toString());
					cv.put("INFO", extraFieldData.get(i).getText().toString());
					cv.put("ORDER_ID", i);
					cv.put("OID", serverID);
					db.insertWithOnConflict("EXTRA_FIELDS", null, cv, SQLiteDatabase.CONFLICT_REPLACE);
				}
				
				cv.clear();
				cv.put(DBOpenHelper.ID, fileName);
				cv.put(DBOpenHelper.STOREAGE_LOCATION, fileLocation);
				cv.put(DBOpenHelper.UID, uid);
				cv.put(DBOpenHelper.TYPE, type);
				cv.put(DBOpenHelper.DATE_CREATED, dateCreated);
				cv.put(DBOpenHelper.LATITUDE, latitude);
				cv.put(DBOpenHelper.LONGITUDE, longitude);
				cv.put(DBOpenHelper.SID, serverID);
				cv.put(DBOpenHelper.TITLE, titleText);
				cv.put(DBOpenHelper.DESCRIPTION, descriptionText);
				cv.put(DBOpenHelper.PRIVACY, privacyLevel);
				cv.put(DBOpenHelper.DATE_MODIFIED, timestamp);
				cv.put(DBOpenHelper.URL, url);
				cv.put(DBOpenHelper.URL_THUMB, url_thumb);
				cv.put(DBOpenHelper.SYNCED, false);
				cv.put(DBOpenHelper.LOCAL_THUMB, local_thumb_location);
				
				db.insertWithOnConflict("OBJECTS", null, cv, SQLiteDatabase.CONFLICT_REPLACE);
				
				cv.clear();
				cv.put("ID", serverID);
				cv.put("TAG", tagsText);
				db.insertWithOnConflict("TAGS", null, cv, SQLiteDatabase.CONFLICT_REPLACE);
								
				db.close();
				data.close();
				//ArrayList<ObjectEntity> e=ApplicationData.getObjects();
				mObjectEntity = new ObjectEntity(this, serverID);
				//e.add(oe);
				//ApplicationData.setObjects(e);
				
				if (synchNow.isChecked())
				{
					synch(mObjectEntity);
				}
				else
					finish();
			}
		}
		else if (v.equals(cancel))// .equals(cancel))
		{
			cancel();
		}
		else if(v.equals(add_field))
		{
			addExtraFieldEditText(null, null);
		}
		else if(v.equals(delete))
		{
			ArrayList<ObjectEntity> ol = ApplicationData.getObjects();
			for(int i=0; i<ol.size(); i++)
			{
				if(ol.get(i).getId()==serverID)
					ol.remove(ol.get(i));
			}
			ApplicationData.setObjects(ol);
			DBOpenHelper data = new DBOpenHelper(this, "mmAppDB", DBOpenHelper.VERSION);
			SQLiteDatabase db = data.getWritableDatabase();
			db.execSQL("Delete from objects where id='"+serverID+"'");
			db.execSQL("Delete from comments where oid="+serverID);
			db.execSQL("Delete from tags where id='"+serverID+"'");
			db.execSQL("Delete from extra_fields where oid="+serverID);
			db.close();
			firstTime=true;
			cancel();
		}
		else if(v.equals(remove_field))
		{
			if(extraFieldTitle.size()>0)
			{
				LinearLayout extraFieldsLayout=(LinearLayout)findViewById(R.id.enter_extra_fields_layout);
				extraFieldsLayout.removeView(extraFieldTitle.remove(extraFieldTitle.size()-1));
				extraFieldsLayout.removeView(extraFieldData.remove(extraFieldData.size()-1));
			}
			
		}
	}
	private void addExtraFieldEditText(String titleText, String fieldText)
	{
		LinearLayout extraFieldsLayout=(LinearLayout)findViewById(R.id.enter_extra_fields_layout);
		EditText et=new EditText(this);
		EditText et1=new EditText(this);
		LayoutParams lp=new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
		et.setLayoutParams(lp);
		et1.setLayoutParams(lp);
		et.setHint("New Field's Title");
		et1.setHint("New Field's Information");
		if(titleText!=null)
		{
			et.setText(titleText);
			et1.setText(fieldText);
		}
		extraFieldsLayout.addView(et);
		extraFieldsLayout.addView(et1);
		extraFieldTitle.add(et);
		extraFieldData.add(et1);
		extraFieldsLayout.invalidate();
	}
	public static boolean validInput(String input)
	{
		String validCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@.-_+! ";
		for (int i = 0; i < input.length(); i++)
		{
			if (!validCharacters.contains(input.subSequence(i, i + 1)))
			{
				return false;
			}
		}
		return true;
	}
	
	private void invalidTextPopup()
	{
		alertPopup("Invalid Text!", "Only use letters, numbers, spaces, and @.-_+!", this);
	}
	private void emptyTextPopup()
	{
		alertPopup("Invalid Text!", "Title fields can not be empty", this);
	}
	static void alertPopup(String popupTitle, String popupMessage, Context c)
	{
		AlertDialog alertDialog = new AlertDialog.Builder(c).create();
		alertDialog.setTitle(popupTitle);
		alertDialog.setMessage(popupMessage);
		alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener()
		{
			public void onClick(DialogInterface dialog, int which)
			{
			}

		});
		alertDialog.show();
	}
	private void getGPSLocation()
	{
		try
		{
			lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
			lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 10f, this);

			Location loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
			latitude = loc.getLatitude();
			longitude = loc.getLongitude();
		}
		catch (NullPointerException e)
		{
			try
			{
				lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
				lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 10f, this);

				Location loc = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
				latitude = loc.getLatitude();
				longitude = loc.getLongitude();
			}
			catch (NullPointerException error)
			{
				AlertDialog alertDialog = new AlertDialog.Builder(InfoActivity.this).create();
				alertDialog.setTitle("ERROR");
				alertDialog.setMessage("GPS is not turned on!");

				alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener()
				{
					public void onClick(DialogInterface dialog, int which)
					{
						cancel();
					}

				});
				alertDialog.show();
			}

		}
	}
	public boolean onKeyDown(int keyCode, KeyEvent event)
	{
		cancel();
		return super.onKeyDown(keyCode, event);
	}
	public void onLocationChanged(Location location)
	{
		longitude = location.getLongitude();
		latitude = location.getLatitude();
	}

	public void onProviderDisabled(String provider)
	{
	}

	public void onProviderEnabled(String provider)
	{
	}

	public void onStatusChanged(String provider, int status, Bundle extras)
	{
	}

	/**
	 * Synch this object.
	 * 
	 * @param oe
	 */
	public void synch(ObjectEntity oe)
	{
		mObjectEntity = oe;
		// Create the progressDialog
		mProgress = new ProgressDialog(this);
		mProgress.setMessage("Synch-ing Media...");
		mProgress.setIndeterminate(true);
		mProgress.setCancelable(false);
		
		// Show the progress while doing the work
		mProgress.show();
		mRequestId = ObjectSyncService.syncRequest(mObjectEntity);
	}

	@Override
	public void onMediaSynchFail(long requestId, String message)
	{
		if (mRequestId == requestId)
		{
			AlertDialog alertDialog = new AlertDialog.Builder(this).create();
			alertDialog.setTitle("Failed");
			alertDialog.setMessage(message);
			alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener()
			{
				public void onClick(DialogInterface dialog, int which)
				{
					mProgress.dismiss();
					finish();
				}

			});
			alertDialog.show();
		}
	}
	@Override
	public void onMediaSynchSuccess(long requestId, long objectId)
	{
		if (mRequestId == requestId)
		{
			
			mObjectEntity.setSynced(true);
			mObjectEntity.setId(objectId);
			mObjectEntity.setLocalId(objectId + "");
			DBOpenHelper data = new DBOpenHelper(this, "mmAppDB", DBOpenHelper.VERSION);
			SQLiteDatabase db = data.getWritableDatabase();
			ContentValues cv = new ContentValues();
			cv.put(DBOpenHelper.ID, objectId);
			db.update("OBJECTS", cv, DBOpenHelper.ID + " = " + serverID, null);
			db.close();
			data.close();
			
			ArrayList<ObjectEntity> ol = ApplicationData.getObjects();
			for(int i=0; i<ol.size(); i++)
			{
				if(ol.get(i).getId()==mObjectEntity.getId())
					ol.remove(ol.get(i));
			}
			ol.add(mObjectEntity);
			ApplicationData.setObjects(ol);
			
			AlertDialog alertDialog = new AlertDialog.Builder(this).create();
			alertDialog.setTitle("Upload");
			alertDialog.setMessage("Do you want to upload the media file now ?");
			alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "Yes", new DialogInterface.OnClickListener()
			{
				public void onClick(DialogInterface dialog, int which)
				{
					mRequestIdUploader = MediaUploader.makeRequest(mObjectEntity.getLocalLocation(), mObjectEntity.getLocalThumb(), mObjectEntity.getId());
				}

			});
			alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "No", new DialogInterface.OnClickListener() {	
				@Override
				public void onClick(DialogInterface dialog, int which)
				{
					mProgress.dismiss();
					finish();
				}
			});
			
			alertDialog.setCancelable(false);		
			alertDialog.show();
		}		
	}
	@Override
	public void onMediaUploaderFail(long requestId, String message)
	{
		if (requestId == mRequestIdUploader)
		{
			AlertDialog alertDialog = new AlertDialog.Builder(this).create();
			alertDialog.setTitle("Failed");
			alertDialog.setMessage(message);
			alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener()
			{
				public void onClick(DialogInterface dialog, int which)
				{
					mProgress.dismiss();
					finish();
				}
			
			});
			alertDialog.show();	
		}
	}
	@Override
	public void onMediaUploaderSuccess(long requestId)
	{
		if (requestId == mRequestIdUploader)
		{
			mProgress.dismiss();
			finish();
		}
	}
}
